package com.robotserver.orders.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.jd.open.api.sdk.DefaultJdClient;
import com.jd.open.api.sdk.JdClient;
import com.robotserver.orders.common.DateUtil;
import com.robotserver.orders.entity.JdOrders;
import com.robotserver.orders.entity.JdTokens;
import com.robotserver.orders.entity.VipOrders;
import com.robotserver.orders.entity.VipTokens;
import com.robotserver.orders.mapper.VipOrdersMapper;
import com.robotserver.orders.mapper.VipTokensMapper;
import com.robotserver.orders.param.JdOrderSyncParam;
import com.robotserver.orders.param.VipOrderSyncParam;
import com.robotserver.orders.param.biz.VipOrderPullParam;
import com.robotserver.orders.service.VipOrderService;
import com.robotserver.orders.service.VipOrderSyncService;
import com.robotserver.orders.vo.VipOrderTimeVO;
import com.robotserver.orders.vo.biz.JdOrderVO;
import com.robotserver.orders.vo.biz.PageVO;
import com.robotserver.orders.vo.biz.VipOrderVO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;


/**
 * @Auther: jianghan
 * @Date: 2020/12/2 11:32
 * @Description:
 */
@Service
public class VipOrderServiceImpl implements VipOrderService {

    private static Logger logger = LoggerFactory.getLogger(VipOrderServiceImpl.class);
    @Autowired
    private VipOrderSyncService vipOrderSyncService;
    @Autowired
    private VipTokensMapper vipTokensMapper;
    @Value("${cluster.group}")
    private String clusterGroup;
    private static int threadRatio = 20;    // 线程比例
    @Autowired
    private VipOrdersMapper vipOrdersMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Async("taskExecutor")
    @Override
    public void syncOrder(VipOrderSyncParam vipOrderSyncParam) {
        try {
            List<VipOrderTimeVO> vipOrderTimeVOS = DateUtil.getVipOrderTimeScope(vipOrderSyncParam.getBegin_time(),vipOrderSyncParam.getEnd_time());

            List<VipTokens> vipTokens = new ArrayList<>();
            int now = DateUtil.getNowTime();
            if (StringUtils.isNotBlank(vipOrderSyncParam.getAccessToken())){
                VipTokens tokens = new VipTokens();
                tokens.setOpenId(vipOrderSyncParam.getOpenId());
                tokens.setAccessToken(vipOrderSyncParam.getAccessToken());
                vipTokens.add(tokens);
            }else {
                // 获取联盟数量
                int count = vipTokensMapper.getCount(now);
                String[] serInfo = clusterGroup.split("_");
                int serCount = Integer.parseInt(serInfo[0]);
                int serInd = Integer.parseInt(serInfo[1]);
                if (count!=0){
                    int vipTokenCount = count/serCount;
                    int vipTokenInd = (vipTokenCount*serInd);
                    if (serInd == serCount-1){
                        vipTokenCount = vipTokenCount+(count%serCount);
                    }
                    vipTokens = vipTokensMapper.getTokens(now,vipTokenInd,vipTokenCount);
                }
            }

            if (vipTokens.size()==0){
                logger.info("vipTokens is null");
                return;
            }

            int threadCount = (vipTokens.size()/threadRatio)+1;
            String lock = clusterGroup+"_vip_order_lock_"+ IdWorker.getId();
            logger.info("vipTokens is :"+vipTokens+",lock:"+lock);
            for (int i=0;i<threadCount;i++){
                vipOrderSyncService.threadSyncOrder(vipOrderTimeVOS,vipTokens,lock,vipOrderSyncParam.getDownTimeType());
            }
        } catch (Exception e) {
            logger.error("err:{}",e);
        }
    }

    @Override
    public PageVO getOrderList(VipOrderPullParam param) {
        List<VipOrders> list = vipOrdersMapper.getOrderList(param);
        VipOrderVO orderVO = new VipOrderVO();
        orderVO.setRecords(list);
        return orderVO;
    }

    @Async("taskExecutor")
    @Override
    public void syncOrder_producer(VipOrderSyncParam vipOrderSyncParam) {
        try {
            //查询两天内修改的唯品会token
            int now = DateUtil.getNowTime();
            List<VipTokens> vipTokensList = vipTokensMapper.getAllTokens(now);
            //往redis队列中塞阿里妈妈tokens
            for (VipTokens vipTokens : vipTokensList) {
                vipTokens.setBeginTime(vipOrderSyncParam.getBegin_time());
                vipTokens.setEndTime(vipOrderSyncParam.getEnd_time());
                vipTokens.setDownTimeType(vipOrderSyncParam.getDownTimeType());
                //对象转成JSON字符串，保存到redis队列中
                String vipTokensStr =  JSONObject.toJSONString(vipTokens);
                redisTemplate.opsForList().leftPush(vipOrderSyncParam.getRedisQueueKey(), vipTokensStr);
                Thread.sleep(0); //0毫秒调用一次
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Async("taskExecutor")
    @Override
    public void syncOrder_consumer(VipOrderSyncParam vipOrderSyncParam) {

        while (true) {
            try {
                //从redis队列中获取联盟
                Object vipTokensObject = redisTemplate.opsForList().rightPop(vipOrderSyncParam.getRedisQueueKey());
                if (vipTokensObject != null) {
                    VipTokens vipTokens = JSONObject.parseObject(vipTokensObject.toString(),VipTokens.class);
                    //封装分段时间查询参数
                    List<VipOrderTimeVO> vipOrderTimeVOS = DateUtil.getVipOrderTimeScope(vipTokens.getBeginTime(),vipTokens.getEndTime());
                    vipOrderSyncService.threadSyncOrder_consumer(vipOrderTimeVOS,vipTokens, vipTokens.getDownTimeType());
                    Thread.sleep(10); //10毫秒调用一次
                }else{
                    // 没有需要处理的数据了
                    logger.info("-------------------------唯品会联盟队列已经消费完成---------------！");
                    break;
                }
            } catch (Exception e) {
                e.printStackTrace();
                break;
            }
        }
    }


}
